#include"TextBox.h"
TextBox::TextBox()
{}
TextBox::TextBox(char *title, int w, int h)
{
	Text = (char *) malloc(TB_BUF);
	Title = (char *) malloc(STR);
	strcpy(Title, title);
	strcpy(Text, "");
	Width = w;
	Height = h;
	DisplayStartIndex = 0;
	Index = 0;
}
TextBox::~TextBox()
{
	free(Text);
	free(Title);
}
/****************************************************************************
 *  Name       : createTextBox
 *  Parameters : Title,
 *               Width of the TextBox and
 *               Height of the TextBox
 *  Returns    : Nothing
 *  Purpose    : To reinitialize an existing object with new values
 ****************************************************************************/
void TextBox::createTextBox(char *title, int w, int h)
{
	Text = (char *) malloc(TB_BUF);
	Title = (char *) malloc(STR);
	strcpy(Title, title);
	strcpy(Text, "");
	Width = w;
	Height = h;
	DisplayStartIndex = 0;
	Index = 0;
}
/****************************************************************************
 *  Name       : setXY
 *  Parameters : x position
 *               y position
 *  Returns    : Nothing
 *  Purpose    : To set the Rectangle values which store the position where
 *               the TextBox will be displayed
 ****************************************************************************/
void TextBox::setXY(int x, int y)
{
	TextRect.left   = x;
	TextRect.top    = y;
	TextRect.right  = x + Width + 2;
	TextRect.bottom = y + 2;
}
/****************************************************************************
 *  Name       : showTitle
 *  Parameters : Status (Active/Inactive)
 *  Returns    : Nothing
 *  Purpose    : To highlight the title if the TextBox is currently active
 ****************************************************************************/
void TextBox::showTitle(int active)
{
	if ( strlen(Title) < Width )
	{
		if ( active > 0 )
			putStr(TextRect.left + 1, TextRect.top, Title, TB_HOT, TB_TXT);
		else
			putStr(TextRect.left + 1, TextRect.top, Title, TB_TXT, TB_HOT);
	}
}
/****************************************************************************
 *  Name       : getText
 *  Parameters : None
 *  Returns    : Text that was entered in the TextBox
 *  Purpose    : To get the contents of the TextBox
 ****************************************************************************/
inline char *TextBox::getText()
{
	return Text;
}
inline int TextBox::getLength()
{
	return Index;
}
/****************************************************************************
 *  Name       : setText
 *  Parameters : Text to be set
 *  Returns    : Nothing
 *  Purpose    : To set a new text to an existing TextBox and to calculate
 *               the new Index and DisplayStartIndex values
 ****************************************************************************/
void TextBox::setText(char *text)
{
	int len;
	strcpy(Text, text);
	len = strlen(Text);
	Index = len - 1; //  Calculate new value so it can be correctly displayed
	DisplayStartIndex = (Width < len) ? len - Width + 1 : 0;
}
/****************************************************************************
 *  Name       : showText
 *  Parameters : None
 *  Returns    : Nothing
 *  Purpose    : Displays the text in the TextBox
 ****************************************************************************/
void TextBox::showText()
{
	int i, len;
	len = strlen(Text);
	for ( i = DisplayStartIndex; i < Width + DisplayStartIndex; i++ )
	{
		if ( i < len )
			putChar(TextRect.left + 1 + i - DisplayStartIndex, TextRect.top + 1, Text[i], TB_TXT);
		else
			putChar(TextRect.left + 1 + i - DisplayStartIndex, TextRect.top + 1, ' ', TB_TXT);
	}
}
/****************************************************************************
 *  Name       : showTextBox
 *  Parameters : None
 *  Returns    : Nothing
 *  Purpose    : To draw the TextBox on the screen
 ****************************************************************************/
void TextBox::showTextBox()
{
	fillBox(TextRect, TB_TXT);
	drawSingleRect(TextRect, TB_TXT);
	showTitle(0);
}
/****************************************************************************
 *  Name       : handleCharEntry
 *  Parameters : Pointer to X position
 *               Pointer to Y position
 *               Character to be entered
 *  Returns    : Nothing
 *  Purpose    : Handles the interaction of the user with the TextBox,
 *               handles the backspace and valid char entry.
 ****************************************************************************/
void TextBox::handleCharEntry(int *x, int *y, char key)
{
	int i;
	if ( key == '\b' )
	{
		if ( *x == TextRect.left + 2 )
		{
			if ( DisplayStartIndex == 0 ) // If
				return;
			else // If more than one width of textbox
			{
				DisplayStartIndex--;
				Text[--Index] = '\0';
				for ( i = DisplayStartIndex; i < Width + DisplayStartIndex; i++ )
				putChar(TextRect.left + 1 + i - DisplayStartIndex, TextRect.top + 1, Text[i], TB_HOT);
			}
		}
		else
		{
			if ( Index <= 0 )
				return;
			else
			{
				Text[--Index] = '\0';
				putChar( (--(*x)) - 1, (*y) - 1, ' ', TB_TXT);
				gotoxy(*x, *y);
			}
		}
	} // Endif ( Backspac)
	else // If printable character
	{
		Text[Index++] = key;
		Text[Index] = '\0';
		if ( Index < Width )
		{
			putChar((*x) - 1, (*y) - 1, key, TB_TXT);
			gotoxy(++(*x), *y);
		}
		else
		{
			DisplayStartIndex++;
			for ( i = DisplayStartIndex; i < Width + DisplayStartIndex; i++ )
				putChar(TextRect.left + 1 + i - DisplayStartIndex, TextRect.top + 1, Text[i], TB_TXT);
		}
	} // Endif (printable character)
}
/****************************************************************************
 *  Name       : handleTextBox
 *  Parameters : None
 *  Returns    : A character, ESC to quit or TAB to shift focus
 *  Purpose    : Handles the interaction of the user with the TextBox.  The
 *               special features of it are that it can handle more text
 *               than the actual width of the TextBox.  Also handles the
 *               backspace event.
 ****************************************************************************/
char TextBox::handleTextBox()
{
	int i, x, y, key;
	x = TextRect.left + (Index + 1) + 2;
	y = TextRect.top + 2;
	showTitle(1);
	gotoxy(x, y);
	while ( 1 )
	{
		if ( kbhit() )
		{
			key = getKey();
			switch ( key )
			{
				case   TAB: showTitle(0);
										return TAB;
				case   ESC: showTitle(0);
										return ESC;
				case  LEFT: break;
				case RIGHT: break;
				default:    if ( isprint(key) || key == '\b' )
											handleCharEntry(&x, &y, key);
			} // End Switch
		} // Endif (If kbhit)
	} // Endwhile (Infinite)
}
// Class TextBox ends